deferred class CD_VECTOR_TEXT
-- It is a text that uses a font created only with line segments. It is very 
-- useful to be scaled and very fast. You must set the text size before drawing 
-- any text. The default direction is horizontal from left to right.
--
-- All vector text drawing in all drivers are simulated with other CD 
-- primitives using polygons only.
	
inherit
	CANVAS_DRAW

feature {ANY}

	draws_vector_text (x, y: INTEGER; text: STRING)
		-- Draws a vector text in position (x,y), respecting the alignment 
		-- defined by "set_text_alignment". It ignores the configuration 
		-- "set_back_opacity", being always transparent. It accepts strings with 
		-- multiple lines using '%n'. It is ESSENTIAL to call 
		-- "set_vector_text_size" or "set_vector_char_size" before using this 
		-- function. 
		do
			int_canvas_vector_text(cnvs, x, y, text.to_external)
		end

	wd_draws_vector_text (x, y: REAL_64; text: STRING)
		-- Like "draws_vector_text" but using World Coordinates.
		do
			int_wd_canvas_vector_text(cnvs, x, y, text.to_external)
		end

	-- Attributes

	set_vector_text_direction (x1, x2, y1, y2: INTEGER)
		-- Defines the text direction by means of two points, (x1,y1) and 
		-- (x2,y2). The default direction is horizontal from left to right. It is 
		-- independent from the transformation matrix.
		do
			int_canvas_vector_text_direction(cnvs, x1, x2, y1, y2)
		end

	set_vector_text_direction_real (x1, x2, y1, y2: REAL_64)
		-- Like "set_vector_text_direction" but using World Coordinates.
		do
			int_canvas_c_double_vector_text_direction(cnvs, x1, x2, y1, y2)
		end

	set_vector_text_transform (matrix: TUPLE[REAL_64, REAL_64, REAL_64, REAL_64, REAL_64, REAL_64]): TUPLE[REAL_64, REAL_64, REAL_64, REAL_64, REAL_64, REAL_64]
		-- Defines a transformation matrix with 6 elements. If the matrix is 
		-- Void, no transformation is set. The default is no transformation. The 
		-- origin is the left bottom corner of matrix. It returns the previous 
		-- matrix, and the returned vector is only valid until the following call 
		-- to the function.
		--
		-- The matrix contains scale, rotation and translation elements. It is 
		-- applied after computing the position and orientation normal to the 
		-- vector text. We can describe the elements as follows:
		--
		-- matrix[0] =    sin(angle)    // Rotation component (can also contain an
		--                                 horizontal shear component)
		-- matrix[1] = scl_y*cos(angle) // Horizontal Scale and Rotation component
		-- matrix[2] = trans_y          // Vertical Translation component
		-- matrix[3] = scl_x*cos(angle) // Vertical Scale and Rotation component
		-- matrix[4] = -sin(angle)      // Rotation component (can also contain a 
		--                                 vertical shear component)
		-- matrix[5] = trans_x          // Horizontal Translation component
		--
		-- It has the same effect of the "set_transform", but notice that the 
		-- indices are different.
		local
			p: POINTER
			m1, m2: NATIVE_ARRAY[REAL_64]
		do
			m1 := m1.calloc(6)

			m1.put(matrix.item_1, 0)
			m1.put(matrix.item_1, 1)
			m1.put(matrix.item_1, 2)
			m1.put(matrix.item_1, 3)
			m1.put(matrix.item_1, 4)
			m1.put(matrix.item_1, 5)

			p := int_canvas_vector_text_transform(cnvs, m1.to_external)

			if p.is_not_null then
				m2 := m2.calloc(6)
				m2 := m2.from_pointer(p)

				Result := [m2.item(0), m2.item(1), m2.item(2), m2.item(3), m2.item(4), m2.item(5)]
			end
		end

	set_vector_text_size (width, height: INTEGER; text: STRING)
		-- Modifies the font size of the vector text so that it fits the string 
		-- in the box defined by width and height.
		do
			int_canvas_vector_text_size(cnvs, width, height, text.to_external)
		end

	set_vector_text_size_real (width, height: REAL_64; text: STRING)
		-- Like "set_vector_text_size" but using REAL_64 values.
		do
			int_canvas_c_double_vector_text_size(cnvs, width, height, text.to_external)
		end

	set_vector_char_size (size: INTEGER)
		-- Modifies the font size by specifying the height of the characters.
		local
			i: INTEGER
		do
			i := int_canvas_vector_char_size(cnvs, size)
		end

	get_vector_char_size: INTEGER
		do
			Result := int_canvas_vector_char_size(cnvs, -1)
		end

	set_vector_char_size_real (size: REAL_64)
		-- Like "set_vector_char_size" but with a REAL_64 value.
		local
			i: REAL_64
		do
			i := int_canvas_c_double_vector_char_size(cnvs, size)
		end

	get_vector_char_size_real: REAL_64
		do
			Result := int_canvas_c_double_vector_char_size(cnvs, -1)
		end

	set_vector_font_size (size_x, size_y: REAL_64)
		-- Directly modifies the font size. Set size_x=size_y to maintain the 
		-- original aspect ratio of the font.
		do
			int_canvas_vector_font_size(cnvs, size_x, size_y)
		end

	get_vector_font_size: TUPLE[REAL_64, REAL_64]
		-- Returns the font size.
		local
			x, y: REAL_64
		do
			int_canvas_get_vector_font_size(cnvs, $x, $y)

			Result := [x, y]
		end

	set_vector_font (filename: STRING): STRING
		-- Replaces the current vector font with a font stored in a file with a 
		-- given name. Returns the name of the font loaded or Void, if it fails. 
		-- If filename is Void, it activates the default font "Simplex II" (There 
		-- is no file associated to this font, it is an embedded font). The 
		-- library will attempt to load a font from the current directory, if it 
		-- fails then it will try the directory defined by the environment 
		-- variable "CDDIR", if it fails, it will attempt to load it using the 
		-- filename as a string containing the font as if the file was loaded 
		-- into that string, if it fails again the font is reset to the default 
		-- font and returns Void. The file format is compatible with the GKS file 
		-- format (text mode).
		local
			p: POINTER
			s: STRING
		do
			p := int_canvas_vector_font(cnvs, filename.to_external)

			if p.is_not_null then
				create s.from_external_copy(p)
				Result := s
			end
		end

	-- Properties

	get_vector_text_size (text: STRING): TUPLE[INTEGER, INTEGER]
		-- Returns the text size independent from orientation.
		local
			width, height: INTEGER
		do
			int_canvas_get_vector_text_size(cnvs, text.to_external, $width, $height)

			Result := [width, height]
		end

	get_vector_text_size_real (text: STRING): TUPLE[REAL_64, REAL_64]
		-- Like "get_vector_text_size" but with REAL_64 values.	
		local
			width, height: REAL_64
		do
			int_canvas_c_double_get_vector_text_size(cnvs, text.to_external, $width, $height)

			Result := [width, height]
		end

	get_vector_text_bounds (x, y: INTEGER; text: STRING): TUPLE[INTEGER, INTEGER, INTEGER, INTEGER, INTEGER, INTEGER, INTEGER, INTEGER]
		-- Returns the oriented bounding rectangle occupied by a text at a given 
		-- position. The rectangle has the same dimentions returned by 
		-- "get_vector_text_size". The rectangle corners are returned in 
		-- counter-clock wise order starting with the bottom left corner, arranged
		-- (x0,y0,x1,y1,x2,y2,x3,y3).	
		local
			points: NATIVE_ARRAY[INTEGER]
		do
			points := points.calloc(8)
			points.set_all_with(0, 7)

			int_canvas_get_vector_text_bounds(cnvs, text.to_external, x, y, points.to_external)

			Result := [points.item(0), points.item(1),
			  	        points.item(2), points.item(3),
				        points.item(4), points.item(5),
				        points.item(6), points.item(7)]
		end

	get_vector_text_bounds_real (x, y: REAL_64; text: STRING): TUPLE[REAL_64, REAL_64, REAL_64, REAL_64, REAL_64, REAL_64, REAL_64, REAL_64]
		-- Like 'get_vector_text_bounds' but with REAL_64 values.
		local
			points: NATIVE_ARRAY[REAL_64]
		do
			points := points.calloc(8)
			points.set_all_with(0, 7)
			
			int_canvas_c_double_get_vector_text_bounds(cnvs, text.to_external, x, y, points.to_external)

			Result := [points.item(0), points.item(1),
			           points.item(2), points.item(3),
			           points.item(4), points.item(5),
			           points.item(6), points.item(7)]
		end

	get_vector_text_box (x, y: INTEGER; text: STRING): TUPLE[INTEGER, INTEGER, INTEGER, INTEGER]
		-- Returns the horizontal bounding rectangle occupied by a text at a 
		-- given position. If orientation is not 0 then its area is always larger 
		-- than the area of the rectangle returned by "get_vector_text_bounds".
		local
			xmin, xmax, ymin, ymax: INTEGER
		do
			int_canvas_get_vector_text_box(cnvs, x, y, text.to_external, $xmin, $xmax, $ymin, $ymax)

			Result := [xmin, xmax, ymin, ymax]
		end

	get_vector_text_box_real (x, y: REAL_64; text: STRING): TUPLE[REAL_64, REAL_64, REAL_64, REAL_64]
		-- Like 'get_vector_text_box' but using REAL_64 values.
		local
			xmin, xmax, ymin, ymax: REAL_64
		do
			int_canvas_c_double_get_vector_text_box(cnvs, x, y, text.to_external, $xmin, $xmax, $ymin, $ymax)

			Result := [xmin, xmax, ymin, ymax]
		end


feature {}

	int_canvas_vector_text(wgt: POINTER; x, y: INTEGER; text: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "cdCanvasVectorText"
         }"
      end

	int_wd_canvas_vector_text(wgt: POINTER; x, y: REAL_64; text: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "wdCanvasVectorText"
         }"
      end

	int_canvas_vector_text_direction(wgt: POINTER; x1, x2, y1, y2: INTEGER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "cdCanvasVectorTextDirection"
         }"
      end

	int_canvas_c_double_vector_text_direction(wgt: POINTER; x1, x2, y1, y2: REAL_64)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "wdCanvasVectorTextDirection"
         }"
      end

	int_canvas_vector_text_transform(wgt, m: POINTER): POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "cdCanvasVectorTextTransform"
         }"
      end

	int_canvas_vector_text_size(wgt: POINTER; w, h: INTEGER; t: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "cdCanvasVectorTextSize"
         }"
      end

	int_canvas_c_double_vector_text_size(wgt: POINTER; w, h: REAL_64; t: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "wdCanvasVectorTextSize"
         }"
      end

	int_canvas_vector_char_size(wgt: POINTER; s: INTEGER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "cdCanvasVectorCharSize"
         }"
      end

	int_canvas_c_double_vector_char_size(wgt: POINTER; s: REAL_64): REAL_64
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "wdCanvasVectorCharSize"
         }"
      end

	int_canvas_vector_font_size(wgt: POINTER; x, y: REAL_64)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "cdCanvasVectorFontSize"
         }"
      end

	int_canvas_get_vector_font_size(wgt, x, y: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "cdCanvasGetVectorFontSize"
         }"
      end

	int_canvas_vector_font(wgt, fn: POINTER): POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "cdCanvasVectorFont"
         }"
      end

	int_canvas_get_vector_text_size(wgt, t, w, h: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "cdCanvasGetVectorTextSize"
         }"
      end

	int_canvas_c_double_get_vector_text_size(wgt, t, w, h: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "wdCanvasGetVectorTextSize"
         }"
      end

	int_canvas_get_vector_text_bounds (wgt, text: POINTER; x, y: INTEGER; r: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "cdCanvasGetVectorTextBounds"
         }"
      end

	int_canvas_c_double_get_vector_text_bounds (wgt, text: POINTER; x, y: REAL_64; r: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "wdCanvasGetVectorTextBounds"
         }"
      end

	int_canvas_get_vector_text_box (wgt: POINTER; x, y: INTEGER; text, xmin, xmax, ymin, ymax: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "cdCanvasGetVectorTextBox"
         }"
      end

	int_canvas_c_double_get_vector_text_box (wgt: POINTER; x, y: REAL_64; text, xmin, xmax, ymin, ymax: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "wdCanvasGetVectorTextBox"
         }"
      end

end

-- The MIT License (MIT)

-- Copyright (c) 2017 by German A. Arias

-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in 
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.
